/**
 * @file app_central.c
 * @author Eker Cheng (yongfei.cheng@onmicro.com.cn)
 * @brief Application interface of central module
 * @version 1.0
 * @date 2022-03-09
 * 
 * @copyright Copyright (c) 2022
 * 
 */
#ifndef __APP_CENTRAL_H__
#define __APP_CENTRAL_H__

#include "prf.h"
#include "rwip_config.h"

#if (BLE_APP_CENTRAL_SUPPORT)

typedef void (*scan_stopped_callback_t)(void);

enum eapp_central_substate
{
    /// activity does not exists
    APP_CENTRAL_SUB_STATE_IDLE = 0,
    /// Creating activity
    APP_CENTRAL_SUB_STATE_CREATING,

    /// activity created
    APP_CENTRAL_SUB_STATE_CREATED,
    /// Starting activity
    APP_CENTRAL_SUB_STATE_STARTING,
    /// activity started
    APP_CENTRAL_SUB_STATE_STARTED,
    /// Stopping activity
    APP_CENTRAL_SUB_STATE_STOPPING,
    /// Stopped activity
    APP_CENTRAL_SUB_STATE_STOPPED,
    /// delete activity
    APP_CENTRAL_SUB_STATE_DELETING,
};

enum eapp_central_state
{
    APP_CENTRAL_STATE_IDLE = 0,
    APP_CENTRAL_STATE_SCAN,
    APP_CENTRAL_STATE_INIT,
};

enum eapp_central_error
{
    APP_CENTRAL_ERROR_NO_ERROR         = 0,
    APP_CENTRAL_ERROR_SCAN_STARTED        ,
    APP_CENTRAL_ERROR_SCAN_FAIL           ,
    APP_CENTRAL_ERROR_CONN_NO_FREE        ,
    APP_CENTRAL_ERROR_CONN_CONNECTING     ,
    APP_CENTRAL_ERROR_CONN_FAIL           ,
};

struct app_central_node_tag
{
    struct gap_bdaddr addr;
    uint16_t mtu;
    uint16_t tx_len;
    uint8_t write_handle[32];
    uint8_t write_handle_num;
    uint8_t ccc_handle[32];
    uint8_t ccc_handle_num;
    uint16_t conhdl;
    uint8_t conidx;
    uint8_t actv_idx;
    uint8_t state;
};

struct app_central_tag
{
    prf_env_t prf_env;

    // for scanning
    uint8_t scan_operation;
    uint8_t scan_state;
    uint8_t scan_actv_idx;
    uint8_t scan_todo; // 1: start; 2: stop

    // for connection
    uint8_t w4connect;
    struct app_central_node_tag connect[BLE_APP_CENTRAL_SUPPORT];
};

/**
 * @brief Find connection information index by connection index
 * 
 * @param conidx: connection index
 * @return uint8_t : connection information index
 */
uint8_t app_central_find_by_conidx(uint8_t conidx);

/**
 * @brief Central module init
 * 
 */
void app_central_init(void);

/**
 * @brief Update central state
 * 
 * @param opera    : activity type, see @ref enum gapm_actv_type
 * @param actv_idx : activity index
 * @param reason   : operation result reason
 */
void app_central_update_state(uint8_t opera, uint8_t actv_idx, uint8_t reason);

/**
 * @brief Start scan
 * 
 * @return uint8_t : error code, see @ref enum eapp_central_error
 */
uint8_t app_central_scan_start(void);

/**
 * @brief Stop scan
 * 
 * @return uint8_t : error code, see @ref enum eapp_central_error
 */
uint8_t app_central_scan_stop(void);

/**
 * @brief Connect the device of "addr".
 * 
 * @param addr : peer device bluetooth address
 * @return uint8_t : error code, see @ref enum eapp_central_error
 */
uint8_t app_central_connect(struct gap_bdaddr addr);

/**
 * @brief Disconnect the device of "conidx"
 * 
 * @param conidx : connection index
 * @return uint8_t : error code, see @ref enum eapp_central_error
 */
uint8_t app_central_disconnect(uint8_t conidx);

/**
 * @brief Set connection handle
 * 
 * @param conidx : connection index
 * @param conhdl : connection handle
 */
void app_central_set_conn_handle(uint8_t conidx, uint16_t conhdl);

/**
 * @brief Set maximum MTU size
 * 
 * @param conidx : connection index
 * @param mtu    : maximum MTU size
 */
void app_central_set_max_mtu(uint8_t conidx, uint16_t mtu);

/**
 * @brief Set Link Layer Tx packet length
 * 
 * @param conidx : connection index
 * @param tx_len : maximum length of Tx
 */
void app_central_set_tx_len(uint8_t conidx, uint16_t tx_len);

/**
 * @brief Get central scan state
 * 
 * @return uint8_t : scan state, see @ref enum eapp_central_substate
 */
uint8_t app_central_get_scan_state(void);

/**
 * @brief Set scan stopped callback function
 * 
 * @param cb : callback function
 */
void app_central_set_scan_stopped_callback(scan_stopped_callback_t cb);

#endif // BLE_APP_CENTRAL_SUPPORT

#endif // __APP_CENTRAL_H__
